package com.rpc.example.handler;

import com.rpc.example.constant.RequestTypeEnum;
import com.rpc.example.core.Header;
import com.rpc.example.core.Protocol;
import com.rpc.example.core.Request;
import com.rpc.example.core.Response;
import com.rpc.example.spring.SpringManager;
import com.rpc.example.spring.service.Median;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author Elvis
 * @version 1.0, 2022/11/10
 */
public class RpcServerHandler extends SimpleChannelInboundHandler<Protocol<Request>> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Protocol<Request> obj) throws Exception {
        Protocol<Response> objectProtocol = new Protocol<>();
        Header header = obj.getHeader();
        header.setRequestType(RequestTypeEnum.RESPONSE.getCode());
        // header.setDataLength(0);

        Object result = Median.getInstance().invoke(obj.getData());
        // Object result = invoke(obj.getData());
        Response response = new Response();
        response.setContent(result);
        response.setMessage("success");
        objectProtocol.setData(response);
        objectProtocol.setHeader(header);
        channelHandlerContext.writeAndFlush(objectProtocol);
    }

    private Object invoke(Request content) {
        try {
            Class<?> clazz = Class.forName(content.getClassName());
            Object bean = SpringManager.getBean(clazz);
            Method declaredMethod = clazz.getDeclaredMethod(content.getMethodName(), content.getParamTypes());
            return declaredMethod.invoke(bean, content.getParams());
        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}
